/***********************************************\
|	"Warehouse's database, Alexander Yushkov"	|
|	- connects.h - most functions from here		|
|		are used directly in main.cpp, so it	|
|		connects modules of lmf::list,			|
|		lmf::base and base's item from			|
|		item.h. Also lmf::vistream for validated|
|		input is defined here.					|
\***********************************************/

#ifndef CONNECTS_H_INCLUDED
#define CONNECTS_H_INCLUDED

#include "../item/item.h"
#include "../list/list.h"
#include "../list_s/list_s.h"
#include "../base/base.h"

void border();
void line(const char*);
void ask(const char*);
void hint();

namespace lmf {

enum t_mode { FULL=0, NODATE=1, NOPRICE=2, NOTHING=3 };
inline t_mode& operator|=(t_mode& to,const t_mode& from)
{
	return to=t_mode(int(to)|int(from));
}

List extract_base(Base&);
List_s extract_log(Base&);
void dump_base(Base&,List&);
void dump_log(Base&,List_s&);
void add_group(List&);
void get_group(List&,List_s&);
void get_group(List&,List_s&,double);
void get_group(List&,List_s&,double,Date);
void get_group(List&,List_s&,double,double);
void get_group(List&,List_s&,double,Date,double);
void print(List&);
void print(List_s&);
void stat_full(List&,List_s&);
void stat_range(List&,List_s&);

class vistream : public std::istream
{
	char delim;
public:
	struct empty {};
	struct corrupted {};

	vistream(char del) : std::istream(std::cin.rdbuf()), delim(del) { unsetf(skipws); /*putback(' ');*/ }
	char set_del(char del)
	{
		char temp=delim;
		delim=del;
		return temp;
	}
	template<typename T>
	vistream& operator>>(T& value) throw(empty,corrupted)
	{
		if(peek()=='\n') get();
		while(peek()==' ') get();
		std::istream::operator>>(value);
		if(fail() && peek()==-1)
		{
			clear();
			ignore(255,'\n');
			putback('\n');
			throw empty();
		}
		else if(fail() || peek()!=delim)
		{
			clear();
			ignore(255,'\n');
			throw corrupted();
		}
		return *this;
	}
};

}

#endif // CONNECTS_H_INCLUDED
